import markdoc from '@astrojs/markdoc';
import react from '@astrojs/react';
import sitemap from '@astrojs/sitemap';
import { defineConfig } from 'astro/config';
import dotenvExpand from 'dotenv-expand';
import * as sass from 'sass';
import { loadEnv } from 'vite';
import mkcert from 'vite-plugin-mkcert';
import svgr from 'vite-plugin-svgr';

import agLinkChecker from '../../external/ag-website-shared/plugins/agLinkChecker';
import buildTime from './plugins/agBuildTime';
import agHotModuleReload from './plugins/agHotModuleReload';
import agHtaccessGen from './plugins/agHtaccessGen';
import agMergeSitemap from './plugins/agMergeSitemap';
import agRedirectsChecker from './plugins/agRedirectsChecker';
import { getSitemapConfig } from './src/utils/sitemap';
import { urlWithBaseUrl } from './src/utils/urlWithBaseUrl';

const { NODE_ENV } = process.env;
const DEFAULT_BASE_URL = '/';
const dotenv = {
    parsed: loadEnv(NODE_ENV, process.cwd(), ''),
};

/**
 * Environment variables used to modify the configuration of the server/build
 */
const {
    /**
     * Port used for servers
     */
    PORT,

    /**
     * Site url
     *
     * eg, `https://grid-staging.ag-grid.com`
     */
    PUBLIC_SITE_URL,

    /**
     * Base url used as a prefix to all urls
     *
     * eg, `/something` for site at `https://grid-staging.ag-grid.com/something`
     */
    PUBLIC_BASE_URL = DEFAULT_BASE_URL,

    /**
     * Use published packages in examples
     */
    PUBLIC_USE_PUBLISHED_PACKAGES,

    /**
     * Use packages for code
     */
    USE_PACKAGES,

    /**
     * Set up https server
     */
    PUBLIC_HTTPS_SERVER = '1',

    /**
     * Show debug logs in the terminal
     *
     * Used to hide logs that are annoying for most other devs
     */
    SHOW_DEBUG_LOGS,

    /**
     * Generate a `.htaccess` file for deployment
     *
     * Generated in `dist/.htaccess`
     */
    HTACCESS = 'false',

    /**
     * Check all redirects have a valid page generated by the build
     *
     * Checks the `to` paths in `src/utils/htaccess/redirects.ts`
     */
    CHECK_REDIRECTS = 'false',

    /**
     * Check all links have valid destinations generated by the build
     */
    CHECK_LINKS = 'false',

    /*
     * Select pages to build
     *
     * A comma separated list of pages to build to make it run faster
     */
    QUICK_BUILD_PAGES,

    /*
     * Disable example runner from rendering
     *
     * Useful for visual regression testing
     */
    DISABLE_EXAMPLE_RUNNER,

    /**
     * Charts sitemap index to merge
     */
    CHARTS_SITEMAP_INDEX_URL,

    /**
     * Charts robots.txt disallow json url to merge
     */
    CHARTS_ROBOTS_DISALLOW_JSON_URL,
} = dotenvExpand.expand(dotenv).parsed;
console.log(
    'Astro configuration',
    JSON.stringify(
        {
            NODE_ENV,
            PORT,
            PUBLIC_SITE_URL,
            PUBLIC_BASE_URL,
            PUBLIC_USE_PUBLISHED_PACKAGES,
            USE_PACKAGES,
            SHOW_DEBUG_LOGS,
            HTACCESS,
            CHECK_LINKS,
            CHECK_REDIRECTS,
            QUICK_BUILD_PAGES,
            DISABLE_EXAMPLE_RUNNER,
            CHARTS_SITEMAP_INDEX_URL,
            CHARTS_ROBOTS_DISALLOW_JSON_URL,
        },
        null,
        2
    )
);

const plugins = [svgr(), agHotModuleReload()];
if (NODE_ENV !== 'test') {
    plugins.push(mkcert()); // mkcert is not necessary for tests
}

// https://astro.build/config
export default defineConfig({
    site: PUBLIC_SITE_URL,
    base: PUBLIC_BASE_URL,
    devToolbar: {
        enabled: false,
    },
    vite: {
        plugins,
        server: {
            https: !['0', 'false'].includes(PUBLIC_HTTPS_SERVER),
            cors: {
                /**
                 * CORS allow list for opening examples on external sites
                 */
                origin: [
                    // Plunkr
                    'https://run.plnkr.co',
                    // Codesandbox
                    /\.csb.app/,
                ],
            },
            headers: {
                'Content-Security-Policy':
                    "default-src 'self'; script-src 'self' https://*.ag-grid.com https://localhost:4610 'unsafe-inline'; style-src 'self' 'unsafe-inline';",
                'X-Content-Type-Options': 'nosniff',
            },
        },
        css: {
            preprocessorOptions: {
                scss: {
                    api: 'modern',
                    functions: {
                        'urlWithBaseUrl($url)': function (args) {
                            const sassUrl = args[0].assertString();
                            const url = sassUrl.toString().replaceAll(/['"]/g, '');
                            const urlWithBase = urlWithBaseUrl(url, PUBLIC_BASE_URL);

                            return new sass.SassString(urlWithBase);
                        },
                    },
                    loadPaths: ['../../external/ag-website-shared/src'],
                },
            },
        },
        optimizeDeps: {
            // Prevent vite from importing in content/docs folder
            exclude: ['vue', '@angular/common/http', '@angular/forms', '@angular/common', '@angular/platform-browser'],
        },
    },
    integrations: [
        buildTime(),
        react(),
        markdoc(),
        sitemap(getSitemapConfig()),
        agHtaccessGen({ include: HTACCESS === 'true' }),
        agRedirectsChecker({
            skip: CHECK_REDIRECTS !== 'true',
        }),
        agLinkChecker({ include: CHECK_LINKS === 'true' }),
        agMergeSitemap({
            // Merge charts sitemap
            sitemapIndexUrl: CHARTS_SITEMAP_INDEX_URL,
        }),
    ],
});
